/*
 * Copyright (C) 2012-2013  Romain DUBOIS
 * 
 * This file is part of NeMoS - Network and Modular Software
 * 
 * NeMoS is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * NeMoS is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with NeMoS.  If not, see <http://www.gnu.org/licenses/>.
 */
package nemos.swing.swixml;

import java.awt.Container;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Locale;
import java.util.Map;

import nemos.resources.IResourcesListener;
import nemos.swing.GenerationException;
import nemos.swing.ISwingGenerator;
import nemos.swing.swixml.customization.NemosEngine;
import nemos.util.i18n.ITranslator;

import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.Service;
import org.osgi.framework.BundleContext;
import org.swixml.Parser;
import org.swixml.SwingEngine;

/**
 * SwingGeneratorImpl : The Swing generator SwiXML implementation.
 * 
 * @author Romain DUBOIS
 */
@Service({ ISwingGenerator.class, IResourcesListener.class })
@Component
public class SwingGeneratorImpl implements ISwingGenerator, IResourcesListener {

    /** The bundle context */
    private BundleContext mContext;
    /** The user locale */
    private Locale mUserLocale;
    /** The translator */
    @Reference(name = "translator")
    private ITranslator mTranslator;
    /** The default resources bundle name */
    private String mUserResources;

    /**
     * Constructor.
     */
    public SwingGeneratorImpl() {
        super();
        SwingEngine.DEBUG_MODE = false;
        Parser.LOCALIZED_ATTRIBUTES.add("headervalue"); //$NON-NLS-1$
    }

    /**
     * Start the component.
     * 
     * @param pContext
     *            The bundle context
     */
    @Activate
    public void start(final BundleContext pContext) {
        mContext = pContext;
    }

    /**
     * {@inheritDoc}
     * 
     * @see nemos.swing.ISwingGenerator#getComponent(java.io.InputStream)
     */
    @Override
    public Container getComponent(final InputStream pInput) throws GenerationException, IOException {
        try {
            return createEngine().render(new InputStreamReader(pInput));
        } catch (final IOException e) {
            throw e;
        } catch (final Exception e) {
            throw new GenerationException(e);
        }
    }

    /**
     * {@inheritDoc}
     * 
     * @see nemos.swing.ISwingGenerator#getComponent(java.io.File)
     */
    @Override
    public Container getComponent(final File pFile) throws GenerationException, IOException {
        try {
            return createEngine().render(pFile);
        } catch (final IOException e) {
            throw e;
        } catch (final Exception e) {
            throw new GenerationException(e);
        }
    }

    /**
     * {@inheritDoc}
     * 
     * @see nemos.swing.ISwingGenerator#getComponents(java.io.InputStream)
     */
    @Override
    public Map<String, Object> getComponents(final InputStream pInput) throws IOException,
            GenerationException {
        try {
            final NemosEngine<?> lEngine = createEngine();
            lEngine.render(new InputStreamReader(pInput));
            return lEngine.getIdMap();
        } catch (final IOException e) {
            throw e;
        } catch (final Exception e) {
            throw new GenerationException(e);
        }
    }

    /**
     * {@inheritDoc}
     * 
     * @see nemos.swing.ISwingGenerator#getComponents(java.io.File)
     */
    @Override
    public Map<String, Object> getComponents(final File pFile) throws IOException,
            GenerationException {
        try {
            final NemosEngine<?> lEngine = createEngine();
            lEngine.render(pFile);
            return lEngine.getIdMap();
        } catch (final IOException e) {
            throw e;
        } catch (final Exception e) {
            throw new GenerationException(e);
        }
    }

    /**
     * {@inheritDoc}
     * 
     * @see nemos.resources.IResourcesListener#userLocaleChanged(java.util.Locale)
     */
    @Override
    public void userLocaleChanged(final Locale pLocale) {
        mUserLocale = pLocale;
    }

    /**
     * {@inheritDoc}
     * 
     * @see nemos.resources.IResourcesListener#userResourcesChanged(java.lang.String)
     */
    @Override
    public void userResourcesChanged(final String pResources) {
        mUserResources = pResources;
    }

    /**
     * Bind the translator service.
     * 
     * @param pTranslator
     *            The translator to bind
     */
    public void bindTranslator(final ITranslator pTranslator) {
        mTranslator = pTranslator;
    }

    /**
     * Unbind the translator service.
     * 
     * @param pTranslator
     *            The translator to unbind
     */
    public void unbindTranslator(@SuppressWarnings("unused") final ITranslator pTranslator) {
        mTranslator = null;
    }

    /**
     * Get a new engine.
     * 
     * @return The new engine to use
     */
    private NemosEngine<?> createEngine() {
        final NemosEngine<?> lEngine = new NemosEngine<Container>(mContext, Container.class,
                mTranslator);
        lEngine.setLocale(mUserLocale);
        lEngine.setResourceBundle(mUserResources);
        return lEngine;
    }
}
